package com.hunter.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.Enumeration;
import java.util.List;

import javax.swing.Box;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;

import com.hunter.desktop.file.FileData;
import com.hunter.desktop.file.fetch.FileFetcher;
import com.hunter.desktop.file.fetch.support.ChooserClause;
import com.hunter.desktop.file.fetch.support.ChooserGroup;
import com.hunter.desktop.file.fetch.support.DirectoryOnly;
import com.hunter.desktop.file.fetch.support.FileOnly;
import com.hunter.desktop.file.fetch.support.ChooserClause.Occur;
import com.hunter.lucene.util.index.IndexException;
import com.hunter.lucene.util.index.Writable;
import com.hunter.util.ConfigManager;
import com.hunter.util.IndexManager;
import com.hunter.util.LogUtil;
import com.mkk.swing.SwingUtil;

/**
 * 2010-9-26 下午10:40:50<br>
 * 管理创建的索引面板
 * 
 * @author mkk
 */
public class IndexsManPanel extends JPanel {

	private static final long serialVersionUID = 1L;

	private SettingDialog main;
	// panel
	private JPanel panel1, panel2, panel3, panel4, panel5;
	// button
	private JButton button3, button4;
	// list
	private JList list;
	private DefaultListModel listModel;
	// label
	private JLabel label1;
	// progressbar
	private JProgressBar bar;
	// indexManager
	private IndexManager indexManager;

	/**
	 * constructor
	 * 
	 * @param main
	 */
	public IndexsManPanel(SettingDialog main) {
		this.main = main;
		this.indexManager = IndexManager.getIndexManager();
		this.initComponents();
		initDatas();
		this.processEvents();
	}

	/**
	 * 初始化数据
	 */
	private void initDatas() {
		List<String> list = this.indexManager.getAllPath();
		if (list.size() > 0) {
			for (String s : list) {
				listModel.addElement(s);
			}
		} else {
			// 提示信息
			setInfo("尚未对任何目录创建索引,请点击左边\"创建索引\"项创建!", Color.BLUE);
		}
	}

	/**
	 * 初始化组件
	 */
	private void initComponents() {
		this.setLayout(new BorderLayout(5, 5));
		// north
		this.panel1 = new JPanel();
		panel1.setLayout(new GridLayout(2, 1, 5, 5));
		JLabel label = new JLabel(" 管理创建的索引");
		label.setFont(new Font("宋体", Font.PLAIN, 16));
		label.setForeground(new Color(0, 0, 204));
		panel1.add(label);
		JSeparator sep = new JSeparator(SwingConstants.HORIZONTAL);
		panel1.add(sep);
		this.add(panel1, BorderLayout.NORTH);
		// center
		this.panel3 = new JPanel(new BorderLayout(5, 5));
		JLabel l = new JLabel("在此更新或删除已创建的索引文件");
		panel3.add(l, BorderLayout.NORTH);
		panel4 = new JPanel(new BorderLayout(5, 5));
		l = new JLabel("已创建的索引的目录列表:");
		l.setForeground(Color.GRAY);
		panel4.add(l, BorderLayout.NORTH);
		list = new JList();
		listModel = new DefaultListModel();
		list.setModel(listModel);
		list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		panel4.add(new JScrollPane(list), BorderLayout.CENTER);
		panel5 = new JPanel(new BorderLayout());
		button3 = new JButton("  更新  ");
		button4 = new JButton("  删除  ");
		button3.setEnabled(false);
		button4.setEnabled(false);
		Box box = Box.createVerticalBox();
		box.add(button3);
		box.add(Box.createVerticalStrut(10));
		box.add(button4);
		panel5.add(box, BorderLayout.CENTER);
		panel4.add(panel5, BorderLayout.EAST);
		bar = new JProgressBar(0, 100);
		bar.setVisible(false);
		panel4.add(bar, BorderLayout.SOUTH);
		panel3.add(panel4, BorderLayout.CENTER);
		this.add(panel3, BorderLayout.CENTER);
		// north
		this.panel2 = new JPanel(new FlowLayout(FlowLayout.LEFT));
		label1 = new JLabel("在列表中选择一个目录,然后点击右边的更新或删除按钮");
		label1.setForeground(Color.GRAY);
		panel2.add(label1);
		this.add(panel2, BorderLayout.SOUTH);

	}

	/**
	 * 事件处理
	 */
	private void processEvents() {
		// 列表点击事件
		this.list.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				int i = list.getSelectedIndex();
				if (i == -1) {
					button3.setEnabled(false);
					button4.setEnabled(false);
				} else {
					button3.setEnabled(true);
					button4.setEnabled(true);
				}
			}
		});
		// 更新事件
		button3.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				int i = list.getSelectedIndex();
				if (i == -1) {
					setInfo("请选择要更新的目录!", Color.BLUE);
					return;
				}
				button3.setEnabled(false);
				bar.setVisible(true);
				// 更新,应该按照创建时的选项来更新对应的目录信息
				// 目前使用默认的更新,即对文件与文件夹更新
				SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {

					@Override
					protected Void doInBackground() throws Exception {
						try {
							publish(1);
							String path = (String) list.getSelectedValue();
							File f = new File(path);
							if (!f.exists()) {
								setInfo("目录 " + f + " 已经不存在,不能更新!", Color.RED);
								return null;
							}
							ChooserClause filec = new ChooserClause(
									new FileOnly(), Occur.SHOULD);
							ChooserClause directory = new ChooserClause(
									new DirectoryOnly(), Occur.SHOULD);
							ChooserGroup group = new ChooserGroup();
							group.add(filec);
							group.add(directory);
							FileFetcher fetcher = new FileFetcher(
									new File[] { f }, group);
							// create index
							Enumeration<FileData> enumeration = fetcher
									.iterator();
							Writable writ = ConfigManager.getManager()
									.getWriter();
							publish(3);
							while (enumeration.hasMoreElements()) {
								FileData fe = enumeration.nextElement();
								setInfo("更新 " + fe.getAbsolutePath(),
										Color.BLUE);
								publish((bar.getValue() + 2) % 100);
								writ.update(fe);
							}
							publish(99);
							// commit
							writ.commit();
							setInfo("更新 " + path + " 完成!", Color.BLUE);
						} catch (Exception e) {
							e.printStackTrace();
							LogUtil.saveExceptionLog(e);
							SwingUtil.showErrorInfo(main, "异常", "更新索引异常,信息:\n"
									+ e.getMessage());
							setInfo("", Color.BLUE);
						}
						return null;
					}

					protected void process(List<Integer> chunks) {
						for (int i : chunks) {
							bar.setValue(i);
						}
					}

					protected void done() {
						button3.setEnabled(true);
						bar.setVisible(false);
					}

				};
				worker.execute();

			}
		});
		// 删除事件
		button4.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				int i = list.getSelectedIndex();
				if (i == -1) {
					setInfo("请选择要删除的目录!", Color.BLUE);
					return;
				}
				setInfo("删除中,请稍候...!", Color.BLUE);
				button4.setEnabled(false);
				EventQueue.invokeLater(new Runnable() {

					public void run() {
						Writable writ = null;
						try {
							String s = (String) list.getSelectedValue();
							File f = new File(s);
							if (!f.exists()) {
								setInfo("目录 " + s + " 已经不存在,删除失败!", Color.RED);
								return;
							}
							writ = ConfigManager.getManager().getWriter();
							writ.remove(f);
							// 从对应集合中删除对应的目录
							indexManager.remove(s);
							// 更新list
							removeElement(s);
							setInfo("删除索引 " + s + " 完成!", Color.BLUE);
							writ.commit();
						} catch (Exception e) {
							if (writ != null) {
								// rollback
								try {
									writ.rollback();
								} catch (IndexException e1) {
									e1.printStackTrace();
									LogUtil.saveExceptionLog(e1);
								}
							}
							e.printStackTrace();
							LogUtil.saveExceptionLog(e);
							SwingUtil.showErrorInfo(main, "异常", "信息:\n"
									+ e.getMessage());
							setInfo("删除索引异常!", Color.black);
						} finally {
							button4.setEnabled(true);
						}

					}
				});

			}
		});

	}

	/**
	 * 从列表中删除指定的项
	 * 
	 * @param path
	 */
	private void removeElement(String path) {
		int size = listModel.getSize();
		for (int i = 0; i < size; i++) {
			String s = (String) listModel.getElementAt(i);
			if (s.equalsIgnoreCase(path)) {
				listModel.removeElement(s);
			}
		}
	}

	/**
	 * 设置状态栏信息
	 * 
	 * @param info
	 * @param c
	 */
	private void setInfo(String info, Color c) {
		label1.setText(info);
		label1.setForeground(c);
	}

}
